package com.gitee.mars.vaccin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gitee.mars.vaccin.entity.SysDept;
import com.gitee.mars.vaccin.exception.WorkException;
import com.gitee.mars.vaccin.mapper.SysDeptMapper;
import com.gitee.mars.vaccin.request.SysDeptReq;
import com.gitee.mars.vaccin.response.vo.DeptDetailVo;
import com.gitee.mars.vaccin.response.vo.SysDeptListVo;
import com.gitee.mars.vaccin.response.vo.SysDeptTreeVo;
import com.gitee.mars.vaccin.service.ISysDeptService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * SysDept 实现层
 *
 * @Author wq
 * @Date 2021-02-04
 **/
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {


    @Override
    public void add(SysDeptReq req) {
        if (StringUtils.isEmpty(req.getName())) {
            throw new WorkException("请输入部门名称");
        }
        SysDept sysDept = new SysDept();
        sysDept.setName(req.getName());
        sysDept.setCreateTime(new Date());
        sysDept.setUpdateTime(new Date());
        sysDept.setParentId(req.getParentId());
        sysDept.setSort(req.getSort());
        sysDept.setMobile(req.getMobile());
        sysDept.setLeader(req.getLeader());
        sysDept.setEmail(req.getEmail());
        sysDept.setStatus(0);
        sysDept.setDeleted(0);
        save(sysDept);
    }

    @Override
    public void delete(Integer id) {
        //查询该部门下是否有子部门
        Integer hasChild = baseMapper.hasChildByDeptId(id);
        if (hasChild > 0) {
            throw new WorkException("该部门下是有子部门,不能删除");
        }
        //检测该部门下是否存在用户
        Integer existUser = baseMapper.checkDeptExistUser(id);
        if (existUser > 0) {
            throw new WorkException("该部门下存在用户,不能删除");
        }
        baseMapper.deleteById(id);
    }

    @Override
    public void update(SysDeptReq req) {
        SysDept sysDept = getById(req.getId());
        if (Objects.isNull(sysDept)) {
            throw new WorkException("数据错误");
        }
        BeanUtils.copyProperties(req, sysDept);
        sysDept.setUpdateTime(new Date());
        updateById(sysDept);
    }

    @Override
    public List<SysDeptListVo> getList(Integer id, String deptName) {
        LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(id)) {
            wrapper.eq(SysDept::getId, id);
        }
        if (StringUtils.isNotEmpty(deptName)) {
            wrapper.like(SysDept::getName, deptName);
        }
        wrapper.orderByDesc(SysDept::getSort);
        List<SysDept> sysDepts = baseMapper.selectList(wrapper);
        return buildDepts(sysDepts, 0, id, deptName);
    }

    @Override
    public String selectDeptName(Integer deptId) {
        return baseMapper.selectDeptName(deptId);
    }

    @Override
    public List<SysDeptTreeVo> treeDept() {
        List<SysDept> deptList = list();
        return treeDept(deptList, 0);
    }

    @Override
    public DeptDetailVo getDeptDetail(Integer id) {
        SysDept sysDept = getById(id);
        if (Objects.nonNull(sysDept)) {
            DeptDetailVo vo = new DeptDetailVo();
            vo.setEmail(sysDept.getEmail());
            vo.setLeader(sysDept.getLeader());
            vo.setMobile(sysDept.getMobile());
            vo.setName(sysDept.getName());
            vo.setSort(sysDept.getSort());
            vo.setStatus(sysDept.getStatus());
            vo.setParentId(sysDept.getParentId());
            vo.setId(sysDept.getId());
            return vo;
        }
        return null;
    }

    /**
     * 构建树形菜单
     *
     * @param sysDepts 菜单ID
     * @param parentId 父级ID
     * @return
     */
    private List<SysDeptTreeVo> treeDept(List<SysDept> sysDepts, Integer parentId) {
        //构建父级部门
        ArrayList<SysDeptTreeVo> list = sysDepts.stream().
                filter(sysDept -> sysDept.getParentId().equals(parentId)).
                map(x -> {
                    SysDeptTreeVo vo = new SysDeptTreeVo();
                    vo.setId(x.getId());
                    vo.setLabel(x.getName());
                    return vo;
                }).collect(Collectors.toCollection(ArrayList::new));
        //遍历所有父部门
        for (SysDeptTreeVo sysDeptListVo : list) {
            //查询该父级部门下的子部门
            List<SysDeptTreeVo> childrenList = treeDept(sysDepts, sysDeptListVo.getId());
            if (childrenList.size() > 0) {
                //将子部门添加父部门
                sysDeptListVo.setChildren(childrenList);
            }
        }
        return list;
    }

    /**
     * 构建部门数
     *
     * @param sysDepts
     * @param parentId
     * @return
     */
    private List<SysDeptListVo> buildDepts(List<SysDept> sysDepts, Integer parentId, Integer id, String deptName) {
        if (Objects.nonNull(id) || StringUtils.isNotEmpty(deptName)) {
            for (SysDept sysDept : sysDepts) {
                if (sysDept.getParentId().equals(parentId)) {
                    return sysDepts.stream().map(this::getSysDeptListVo).collect(Collectors.toList());
                }
            }
            //搜索
            return sysDepts.stream().filter(sysDept -> !sysDept.getParentId().equals(parentId)).
                    map(this::getSysDeptListVo).collect(Collectors.toList());
        }
        //构建父级部门
        ArrayList<SysDeptListVo> list = sysDepts.stream().
                filter(sysDept -> sysDept.getParentId().equals(parentId)).
                map(this::getSysDeptListVo).collect(Collectors.toCollection(ArrayList::new));
        //遍历所有父部门
        for (SysDeptListVo sysDeptListVo : list) {
            //查询该父级部门下的子部门
            List<SysDeptListVo> childrenDepts = buildDepts(sysDepts, sysDeptListVo.getId(), id, deptName);
            if (childrenDepts.size() > 0) {
                //将子部门添加父部门
                sysDeptListVo.setChildren(childrenDepts);
            }
        }
        return list;
    }


    /**
     * 构建返回参数
     *
     * @param x x
     * @return SysDeptListVo
     */
    private SysDeptListVo getSysDeptListVo(SysDept x) {
        SysDeptListVo vo = new SysDeptListVo();
        vo.setId(x.getId());
        vo.setEmail(x.getEmail());
        vo.setLeader(x.getLeader());
        vo.setMobile(x.getMobile());
        vo.setSort(x.getSort());
        vo.setCreateTime(x.getCreateTime());
        vo.setUpdateTime(x.getUpdateTime());
        vo.setParentId(x.getParentId());
        vo.setStatus(x.getStatus());
        vo.setName(x.getName());
        return vo;
    }
}